home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
ddj9304.zip
/
WAVELET.ZIP
/
WAVE_BLD.C
< prev
next >
Wrap
Text File
|
1992-05-18
|
9KB
|
331 lines
/* WAVE_BLD.C */
#define WAVE_BLD
#include <math.h>
#include <alloc.h>
#include "wave_bld.h"
typedef enum {DECOMP, RECON} wavetype;
double **BuildWaveStorage(int inlength, int *levels);
void DestroyWaveStorage(double **tree, int levels);
void WaveletCoeffs(double alpha, double beta, double *wavecoeffs);
char MakeWaveletFilters(double *wavecoeffs, double *Lfilter,
double *Hfilter, wavetype transform);
double DotpEven(double *data, double *filter, char filtlength);
double DotpOdd(double *data, double *filter, char filtlength);
void ConvolveInt2(double *input_sequence, int inp_length, double *filter,
char filtlen, char sum_output, double *output_sequence);
void ScalingFuncRegeneration(double **InData, int Inlength,
double *Lfilter, char filtlen, char levels, double *OutData);
void WaveletRegeneration(double **InData, int Inlength, double *Lfilter,
double *Hfilter, char filtlen, char levels, double *OutData);
double DataSetMagnitude(double *data, int length);
double wavedata[901], wave_coeff[6];
double g[6], gtilda[6], h[6], htilda[6];
double **ExCoeffPhi, **ExCoeffPsi;
int wave_levels;
double **BuildWaveStorage(int inlength, int *levels)
{
double **tree;
int i, j, lvls;
lvls = *levels;
/* create decomposition tree */
tree = (double **) calloc(lvls, sizeof(double *));
j = inlength;
for (i = 0; i < lvls; i++)
{
j /= 2;
if (j == 0) /* too many levels requested for available data */
{ /* number of transform levels now set to value of i */
*levels = i;
continue;
}
tree[i] = (double *) calloc((j + 5), sizeof(double));
}
return tree;
}
void DestroyWaveStorage(double **tree, int levels)
{
char i;
for (i = levels - 1; i >= 0; i--)
free(tree[i]);
free(tree);
}
void WaveletCoeffs(double alpha, double beta, double *wavecoeffs)
{
double tcosa, tcosb, tsina, tsinb;
char i;
/* precalculate cosine of alpha and sine of beta to reduce */
/* processing time */
tcosa = cos(alpha);
tcosb = cos(beta);
tsina = sin(alpha);
tsinb = sin(beta);
/* calculate first two wavelet coefficients a = a(-2) and b = a(-1) */
wavecoeffs[0] = ((1.0 + tcosa + tsina) * (1.0 - tcosb - tsinb)
+ 2.0 * tsinb * tcosa) / 4.0;
wavecoeffs[1] = ((1.0 - tcosa + tsina) * (1.0 + tcosb - tsinb)
- 2.0 * tsinb * tcosa) / 4.0;
tcosa = cos(alpha - beta); /* precalculate cosine and sine of alpha */
tsina = sin(alpha - beta); /* minus beta to reduce processing time */
/* calculate last four wavelet coefficients c = a(0), d = a(1), */
/* e = a(2), and f = a(3) */
wavecoeffs[2] = (1.0 + tcosa + tsina) / 2.0;
wavecoeffs[3] = (1.0 + tcosa - tsina) / 2.0;
wavecoeffs[4] = 1 - wavecoeffs[0] - wavecoeffs[2];
wavecoeffs[5] = 1 - wavecoeffs[1] - wavecoeffs[3];
/* zero out very small coefficient values caused by truncation error */
for (i = 0; i < 6; i++)
{
if (fabs(wavecoeffs[i]) < 1.0e-15)
wavecoeffs[i] = 0.0;
}
}
char MakeWaveletFilters(double *wavecoeffs, double *Lfilter,
double *Hfilter, wavetype transform)
{
char i, j, k, filterlength;
i = 0; /* find the first non-zero wavelet coefficient */
while(wavecoeffs[i] == 0.0)
i++;
j = 5; /* find the last non-zero wavelet coefficient */
while(wavecoeffs[j] == 0.0)
j--;
/* form the decomposition filters h~ and g~ or the reconstruction
filters h and g. the division by 2 in the construction
of the decomposition filters is for normalization */
filterlength = j - i + 1;
for(k = 0; k < filterlength; k++)
{
if (transform == DECOMP)
{
Lfilter[k] = wavecoeffs[j--] / 2.0;
Hfilter[k] = (double) (((i++ & 0x01) * 2) - 1) * wavecoeffs[i] / 2.0;
}
else
{
Lfilter[k] = wavecoeffs[i++];
Hfilter[k] = (double) (((j-- & 0x01) * 2) - 1) * wavecoeffs[j];
}
}
while (k < 6) /* clear out the additional array locations, if any */
{
Lfilter[k] = 0.0;
Hfilter[k++] = 0.0;
}
return filterlength;
}
double DotpEven(double *data, double *filter, char filtlen)
{
char i;
double sum;
sum = 0.0;
for (i = 0; i < filtlen; i += 2)
sum += *data-- * filter[i]; /* decreasing data pointer is moving */
/* backward in time */
return sum;
}
double DotpOdd(double *data, double *filter, char filtlen)
{
char i;
double sum;
sum = 0.0;
for (i = 1; i < filtlen; i += 2)
sum += *data-- * filter[i]; /* decreasing data pointer is moving */
/* backward in time */
return sum;
}
void ConvolveInt2(double *input_sequence, int inp_length, double *filter,
char filtlen, char sum_output, double *output_sequence)
/* insert zeros between each element of the input sequence and
convolve with the filter to interpolate the data */
{
int i;
if (sum_output) /* summation with previous convolution if true */
{
/* every other dot product interpolates the data */
for(i = (filtlen / 2) - 1; i < inp_length + filtlen - 2; i++)
{
*output_sequence++ += DotpOdd(input_sequence + i, filter, filtlen);
*output_sequence++ += DotpEven(input_sequence + i + 1, filter, filtlen);
}
*output_sequence++ += DotpOdd(input_sequence + i, filter, filtlen);
}
else /* first convolution of pair if false */
{
/* every other dot product interpolates the data */
for(i = (filtlen / 2) - 1; i < inp_length + filtlen - 2; i++)
{
*output_sequence++ = DotpOdd(input_sequence + i, filter, filtlen);
*output_sequence++ = DotpEven(input_sequence + i + 1, filter, filtlen);
}
*output_sequence++ = DotpOdd(input_sequence + i, filter, filtlen);
}
}
void ScalingFuncRegeneration(double **InData, int Inlength,
double *Lfilter, char filtlen, char levels, double *OutData)
/* assumes that the input data has (2^levels) data points per unit
interval */
{
double *Output;
char i;
Inlength = Inlength >> levels;
/* destination of all but last branch reconstruction is the next
higher intermediate approximation */
for (i = levels - 1; i > 0; i--)
{
Output = InData[i - 1];
ConvolveInt2(InData[i], Inlength, Lfilter, filtlen, 0, Output);
Inlength *= 2;
}
/* destination of the last branch reconstruction is the output data */
ConvolveInt2(InData[0], Inlength, Lfilter, filtlen, 0, OutData);
}
void WaveletRegeneration(double **InData, int Inlength, double *Lfilter,
double *Hfilter, char filtlen, char levels, double *OutData)
/* assumes the input data has (2^levels) data points per unit interval */
{
double *Output;
char i;
Inlength = Inlength >> levels;
ConvolveInt2(InData[levels - 1], Inlength, Hfilter, filtlen,
0, InData[levels - 2]);
Inlength *= 2;
/* destination of all but last branch reconstruction is the next
higher intermediate approximation */
for (i = levels - 2; i > 0; i--)
{
Output = InData[i - 1];
ConvolveInt2(InData[i], Inlength, Lfilter, filtlen, 0, Output);
Inlength *= 2;
}
/* destination of the last branch reconstruction is the output data */
ConvolveInt2(InData[0], Inlength, Lfilter, filtlen, 0, OutData);
}
double DataSetMagnitude(double *data, int length)
{
int i;
double newval, maxval;
if (data[0] < 0) /* initial seed for largest magnitude of data set */
maxval = -data[0];
else
maxval = data[0];
for (i = 1; i < length; i++)
{ /* determine largest magnitude of data set */
if (data[i] < 0)
newval = -data[i];
else
newval = data[i];
if (newval > maxval)
maxval = newval;
}
if (maxval == 0.0) /* default value if all data points are zero */
maxval = 1.0;
return maxval;
}
void SetupWaveletConstruction(void)
{
wave_levels = 6;
ExCoeffPhi = BuildWaveStorage(448, &wave_levels);
ExCoeffPsi = BuildWaveStorage(448, &wave_levels);
ExCoeffPhi[5][5] = 1.0; /* reconstruction from a single impulse ... */
ExCoeffPsi[5][5] = 1.0; /* yields the scaling or wavelet function */
PhiData = wavedata; /* both functions are in one array */
PsiData = &wavedata[448];
}
void BuildDSPfilterArray(double alpha, double beta, float *DSPfilters)
{
int i, j, filtlen;
/* determine wavelet coefficients for DSP */
WaveletCoeffs(alpha, beta, wave_coeff);
MakeWaveletFilters(wave_coeff, htilda, gtilda, DECOMP);
/* place filters in array for download to DSP board */
i = 0;
for (j = 0; j < 6; j++)
DSPfilters[i++] = (float) gtilda[j];
for (j = 0; j < 6; j++)
DSPfilters[i++] = (float) htilda[j];
/* determine wavelet coefficients for function calculations */
filtlen = MakeWaveletFilters(wave_coeff, h, g, RECON);
for (i = 896; i < 901; i++) /* zeroo out end effects */
wavedata[i] = 0.0;
ScalingFuncRegeneration(ExCoeffPhi, 448, h, filtlen, 6, PhiData);
WaveletRegeneration(ExCoeffPsi, 448, h, g, filtlen, 6, PsiData);
magnitude = DataSetMagnitude(wavedata, 901);
/* depending upon length of the filters,
the functions will be offset by a fixed amount */
switch(filtlen)
{
case 2:
offset = 128;
break;
case 4:
offset = 64;
break;
case 6:
offset = 0;
}
}